home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!ogicse!zephyr.ens.tek.com!tekred!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v11i009: tinymud2 - user-extendible multi-user adventure (v1.5.4), Part05/10
- Message-ID: <6054@tekred.CNA.TEK.COM>
- Date: 30 Jul 90 16:45:30 GMT
- Sender: news@tekred.CNA.TEK.COM
- Lines: 2211
- Approved: billr@saab.CNA.TEK.COM
- Posted: Mon Jul 30 09:45:30 1990
-
- Submitted-by: James Aspnes <asp@cs.cmu.edu>
- Posting-number: Volume 11, Issue 9
- Archive-name: tinymud2/Part05
- Supersedes: tinymud: Volume 8, Issue 80-83
-
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 5 (of 10)."
- # Contents: interface.c joinspl.sh wiz.c
- # Wrapped by billr@saab on Fri Jul 27 15:27:46 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'interface.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'interface.c'\"
- else
- echo shar: Extracting \"'interface.c'\" \(33958 characters\)
- sed "s/^X//" >'interface.c' <<'END_OF_FILE'
- X/* Concentrator upgraded June 1990 Robert Hood */
- X
- X/* modifed Concentrator to match Fuzzy & Randoms 1.5.4 changes = 6/90 Fuzzy */
- X
- X/* modified interface.c to support LOTS of people, using a concentrator */
- X/* May 1990, Robert Hood */
- X
- X/* #define CHECKC /* consistency checking */
- X
- X#include <stdio.h>
- X#include <sys/param.h>
- X#include <sys/types.h>
- X#include <sys/file.h>
- X#include <sys/time.h>
- X#include <signal.h>
- X#include <sys/ioctl.h>
- X#include <sys/wait.h>
- X#include <fcntl.h>
- X#include <sys/errno.h>
- X#include <ctype.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X
- X#include "config.h"
- X#include "db.h"
- X#include "interface.h"
- X
- X#define BUFSIZE 0xFFFF
- X
- Xstruct text_block
- X{
- X int nchars;
- X struct text_block *nxt;
- X char *start;
- X char *buf;
- X};
- X
- Xstruct text_queue
- X{
- X struct text_block *head;
- X struct text_block **tail;
- X};
- X
- Xstruct descriptor_data
- X{
- X int descriptor;
- X int num;
- X int connected;
- X dbref player;
- X char *output_prefix;
- X char *output_suffix;
- X int output_size;
- X struct text_queue output;
- X struct text_queue input;
- X char *raw_input;
- X char *raw_input_at;
- X long connected_at;
- X long last_time;
- X int quota;
- X struct sockaddr_in address; /* added 3/6/90 SCG */
- X char *hostname; /* 5/18/90 - Fuzzy */
- X struct descriptor_data *next;
- X};
- X
- X#define MALLOC(result, type, number) do { \
- X if (!((result) = (type *) malloc ((number) * sizeof (type)))) \
- X panic("Out of memory"); \
- X } while (0)
- X
- X#define FREE(x) (free((void *) x))
- X
- Xstruct message
- X{
- X char *data;
- X short len;
- X struct message *next;
- X};
- X
- Xstruct conc_list
- X{
- X struct conc_list *next;
- X int sock, current, status;
- X struct descriptor_data *firstd;
- X struct message *first, *last;
- X char *incoming, *outgoing;
- X int ilen, olen;
- X} *firstc = 0;
- X
- Xvoid queue_message(struct conc_list * c, char *data, int len);
- Xvoid start_log();
- Xstruct timeval timeval_sub(struct timeval now, struct timeval then);
- Xstruct timeval msec_add(struct timeval t, int x);
- Xstruct timeval update_quotas(struct timeval last, struct timeval current);
- Xvoid main_loop();
- Xint notify(dbref player, const char *msg);
- Xvoid process_output(struct conc_list * c);
- Xint process_input(struct descriptor_data * d, char *buf, int got);
- Xvoid process_commands();
- Xvoid dump_users(struct descriptor_data * e, char *user);
- Xvoid free_text_block(struct text_block * t);
- Xvoid main(int argc, char **argv);
- Xvoid set_signals();
- Xint msec_diff(struct timeval now, struct timeval then);
- Xvoid clearstrings(struct descriptor_data * d);
- Xvoid shutdownsock(struct descriptor_data * d);
- Xstruct descriptor_data *initializesock(struct sockaddr_in * a);
- Xstruct text_block *make_text_block(const char *s, int n);
- Xvoid add_to_queue(struct text_queue * q, const char *b, int n);
- Xint flush_queue(struct text_queue * q, int n);
- Xint queue_write(struct descriptor_data * d, const char *b, int n);
- Xint queue_string(struct descriptor_data * d, const char *s);
- Xvoid freeqs(struct descriptor_data * d);
- Xvoid welcome_user(struct descriptor_data * d);
- Xvoid do_motd(dbref);
- Xchar *strsave(const char *s);
- Xvoid save_command(struct descriptor_data * d, const char *command);
- Xvoid set_userstring(char **userstring, const char *command);
- Xint do_command(struct descriptor_data * d, char *command);
- Xvoid check_connect(struct descriptor_data * d, const char *msg);
- Xvoid parse_connect(const char *msg, char *command, char *user, char *pass);
- Xvoid close_sockets();
- Xvoid emergency_shutdown(void);
- Xvoid boot_off(dbref player);
- Xint bailout(int sig, int code, struct sigcontext * scp);
- Xchar *time_format_1(long dt);
- Xchar *time_format_2(long dt);
- X#ifdef CONNECT_MESSAGES
- Xvoid announce_connect(dbref);
- Xvoid announce_disconnect(dbref);
- X#endif /* CONNECT_MESSAGES */
- Xint sigshutdown(int, int, struct sigcontext *);
- X
- Xint logsynch();
- Xchar *logfile = LOG_FILE;
- X
- Xint debug;
- Xvoid chg_userid();
- Xvoid file_date(struct descriptor_data * d, const char *file);
- X
- Xstatic const char *connect_fail = "Either that player does not exist, or has a different password.\n";
- X#ifndef REGISTRATION
- Xstatic const char *create_fail = "Either there is already a player with that name, or that name is illegal.\n";
- X#endif /* REGISTRATION */
- Xstatic const char *flushed_message = "<Output Flushed>\n";
- Xstatic const char *shutdown_message = "Going down - Bye\n";
- X
- Xint sock;
- Xint shutdown_flag = 0;
- X
- Xint port = TINYPORT;
- Xint intport = INTERNAL_PORT;
- X
- X
- Xstart_port()
- X{
- X int temp;
- X struct sockaddr_in sin;
- X
- X sock = socket(AF_INET, SOCK_STREAM, 0);
- X if (sock < 1)
- X {
- X perror("socket");
- X exit(-1);
- X }
- X temp = 1;
- X setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&temp, sizeof(temp));
- X sin.sin_family = AF_INET;
- X sin.sin_port = htons(intport);
- X sin.sin_addr.s_addr = htonl(INADDR_ANY);
- X
- X temp = bind(sock, (struct sockaddr *) & sin, sizeof(sin));
- X if (temp < 0)
- X {
- X perror("bind");
- X exit(-1);
- X }
- X temp = listen(sock, 5);
- X if (temp < 0)
- X {
- X perror("listen");
- X exit(-1);
- X }
- X}
- X
- Xstruct timeval
- X timeval_sub(struct timeval now, struct timeval then)
- X{
- X now.tv_sec -= then.tv_sec;
- X now.tv_usec -= then.tv_usec;
- X if (now.tv_usec < 0)
- X {
- X now.tv_usec += 1000000;
- X now.tv_sec--;
- X }
- X return now;
- X}
- X
- Xstruct timeval
- X msec_add(struct timeval t, int x)
- X{
- X t.tv_sec += x / 1000;
- X t.tv_usec += (x % 1000) * 1000;
- X if (t.tv_usec >= 1000000)
- X {
- X t.tv_sec += t.tv_usec / 1000000;
- X t.tv_usec = t.tv_usec % 1000000;
- X }
- X return t;
- X}
- X
- Xstruct timeval
- X update_quotas(struct timeval last, struct timeval current)
- X{
- X int nslices;
- X struct descriptor_data *d;
- X struct conc_list *c;
- X
- X nslices = msec_diff(current, last) / COMMAND_TIME_MSEC;
- X
- X if (nslices > 0)
- X {
- X for (c = firstc; c; c = c->next)
- X for (d = c->firstd; d; d = d->next)
- X {
- X d->quota += COMMANDS_PER_TIME * nslices;
- X if (d->quota > COMMAND_BURST_SIZE)
- X d->quota = COMMAND_BURST_SIZE;
- X }
- X }
- X return msec_add(last, nslices * COMMAND_TIME_MSEC);
- X}
- X
- Xint
- X notify(dbref player2, const char *msg)
- X{
- X struct descriptor_data *d;
- X struct conc_list *c;
- X int retval = 0;
- X
- X#ifdef COMPRESS
- X extern const char *uncompress(const char *);
- X
- X msg = uncompress(msg);
- X#endif /* COMPRESS */
- X for (c = firstc; c; c = c->next)
- X for (d = c->firstd; d; d = d->next)
- X {
- X if (d->connected && d->player == player2)
- X {
- X queue_string(d, msg);
- X queue_write(d, "\n", 1);
- X retval++;
- X }
- X }
- X return (retval);
- X}
- X
- Xint
- X process_input(d, buf, got)
- X struct descriptor_data *d;
- X char *buf;
- X int got;
- X{
- X char *p, *pend, *q, *qend;
- X
- X d->last_time = time(0);
- X if (!d->raw_input)
- X {
- X MALLOC(d->raw_input, char, MAX_COMMAND_LEN);
- X d->raw_input_at = d->raw_input;
- X }
- X p = d->raw_input_at;
- X pend = d->raw_input + MAX_COMMAND_LEN - 1;
- X for (q = buf, qend = buf + got; q < qend; q++)
- X {
- X if (*q == '\n')
- X {
- X *p = '\0';
- X if (p > d->raw_input)
- X save_command(d, d->raw_input);
- X p = d->raw_input;
- X } else
- X if (p < pend && isascii(*q) && isprint(*q))
- X {
- X *p++ = *q;
- X }
- X }
- X if (p > d->raw_input)
- X {
- X d->raw_input_at = p;
- X } else
- X {
- X FREE(d->raw_input);
- X d->raw_input = 0;
- X d->raw_input_at = 0;
- X }
- X return 1;
- X}
- X
- Xvoid process_commands()
- X{
- X int nprocessed;
- X struct descriptor_data *d, *dnext, *dlast;
- X struct conc_list *c;
- X struct text_block *t;
- X char header[4];
- X
- X do
- X {
- X nprocessed = 0;
- X for (c = firstc; c; c = c->next)
- X {
- X dlast = 0;
- X for (d = c->firstd; d; d = dnext)
- X {
- X dnext = d->next;
- X if (d->quota > 0 && (t = d->input.head))
- X {
- X d->quota--;
- X nprocessed++;
- X if (!do_command(d, t->start))
- X {
- X header[0] = 0;
- X header[1] = 2;
- X header[2] = d->num;
- X queue_message(c, header, 3);
- X if (dlast)
- X dlast->next = dnext;
- X else
- X c->firstd = dnext;
- X shutdownsock(d);
- X FREE(d);
- X break;
- X } else
- X {
- X d->input.head = t->nxt;
- X if (!d->input.head)
- X d->input.tail = &d->input.head;
- X free_text_block(t);
- X }
- X }
- X dlast = d;
- X }
- X }
- X } while (nprocessed > 0);
- X}
- X
- Xvoid dump_users(struct descriptor_data * e, char *user)
- X{
- X static struct conc_list *rwclist[NOFILE];
- X static struct descriptor_data *rwdlist[NOFILE];
- X int ccount, dcount, dloop, cloop;
- X
- X struct descriptor_data *d;
- X struct conc_list *c;
- X long now;
- X int counter = 0;
- X static int maxcounter = 0;
- X int wizard, reversed, tabular;
- X char buf[1024];
- X
- X
- X# ifdef DO_WHOCHECK
- X writelog("WHO CHECK %d\n", sizeof(rwclist));
- X writelog("WHO CHECK %d\n", sizeof(rwdlist));
- X# endif
- X
- X while (*user && isspace(*user))
- X user++;
- X if (!*user)
- X user = NULL;
- X
- X reversed = e->connected && Flag(e->player, REVERSED_WHO);
- X tabular = e->connected && Flag(e->player, TABULAR_WHO);
- X
- X time(&now);
- X
- X queue_string(e, tabular ? "Player Name On For Idle\n" :
- X "Current Players:\n");
- X#ifdef GOD_MODE
- X wizard = e->connected && God(e->player);
- X#else GOD_MODE
- X wizard = e->connected && Wizard(e->player);
- X#endif GOD_MODE
- X
- X if (reversed)
- X {
- X ccount = 0;
- X for (c = firstc; c; c = c->next)
- X rwclist[ccount++] = c;
- X for (cloop = ccount - 1; cloop >= 0; --cloop)
- X {
- X dcount = 0;
- X for (d = rwclist[cloop]->firstd; d; d = d->next)
- X rwdlist[dcount++] = d;
- X for (dloop = dcount - 1; dloop >= 0; --dloop)
- X {
- X d = rwdlist[dloop];
- X if (d->connected &&
- X ++counter && /* Count everyone connected */
- X (!user || string_prefix(db[d->player].name, user)))
- X {
- X if (tabular)
- X {
- X sprintf(buf, "%-16s %10s %4s",
- X db[d->player].name,
- X time_format_1(now - d->connected_at),
- X time_format_2(now - d->last_time));
- X
- X if (wizard)
- X sprintf(buf, "%s %s", buf, d->hostname);
- X } else
- X {
- X sprintf(buf, "%s idle %d seconds",
- X db[d->player].name, now - d->last_time);
- X if (wizard)
- X sprintf(buf, "%s from host %s", buf, d->hostname);
- X }
- X strcat(buf, "\n");
- X queue_string(e, buf);
- X }
- X }
- X }
- X } else
- X {
- X for (c = firstc; c; c = c->next)
- X {
- X for (d = c->firstd; d; d = d->next)
- X {
- X if (d->connected &&
- X ++counter && /* Count everyone connected */
- X (!user || string_prefix(db[d->player].name, user)))
- X {
- X if (tabular)
- X {
- X sprintf(buf, "%-16s %10s %4s",
- X db[d->player].name,
- X time_format_1(now - d->connected_at),
- X time_format_2(now - d->last_time));
- X
- X if (wizard)
- X sprintf(buf, "%s %s", buf, d->hostname);
- X } else
- X {
- X sprintf(buf, "%s idle %d seconds",
- X db[d->player].name, now - d->last_time);
- X if (wizard)
- X sprintf(buf, "%s from host %s", buf, d->hostname);
- X }
- X strcat(buf, "\n");
- X queue_string(e, buf);
- X }
- X }
- X }
- X }
- X
- X if (counter > maxcounter)
- X { maxcounter = counter;
- X if (counter > 30)
- X { writelog ("%d users logged in\n", counter); }
- X }
- X
- X sprintf(buf, "%d user%s connected\n", counter,
- X counter == 1 ? " is" : "s are");
- X queue_string(e, buf);
- X}
- X
- Xvoid free_text_block(struct text_block * t)
- X{
- X FREE(t->buf);
- X FREE((char *)t);
- X}
- X
- X#ifndef BOOLEXP_DEBUGGING
- Xvoid main(int argc, char **argv)
- X{
- X int pid;
- X
- X if (argc < 3)
- X {
- X fprintf(stderr, "Usage: %s infile dumpfile [port iport logfile]\n", *argv);
- X exit(1);
- X
- X }
- X if (argc > 3)
- X port = atoi(argv[3]);
- X if (argc > 4)
- X intport = atoi(argv[4]);
- X if (argc > 5)
- X logfile = argv[5];
- X
- X start_log();
- X
- X if (init_game(argv[1], argv[2]) < 0)
- X {
- X writelog("INIT: Couldn't load %s\n", argv[1]);
- X exit(2);
- X }
- X pid = vfork();
- X if (pid < 0)
- X {
- X perror("fork");
- X exit(-1);
- X }
- X if (pid == 0)
- X {
- X char pstr[32], istr[32], clvl[32];
- X
- X /* Add port argument to concentrator */
- X sprintf(pstr, "%d", port);
- X sprintf(istr, "%d", intport);
- X sprintf(clvl, "%d", 1);
- X execl("concentrate", "conc", pstr, istr, clvl, 0);
- X }
- X set_signals();
- X start_port(port);
- X main_loop();
- X close_sockets();
- X dump_database();
- X exit(0);
- X}
- X
- X#endif
- X
- Xvoid start_log()
- X{
- X#ifdef DETACH
- X if (!debug)
- X {
- X int i;
- X
- X if (fork() != 0)
- X exit(0);
- X
- X i = open("/dev/tty", O_RDWR, 0);
- X if (i != -1)
- X {
- X ioctl(i, TIOCNOTTY, 0);
- X close(i);
- X }
- X }
- X freopen(logfile, "a", stderr);
- X setbuf(stderr, NULL);
- X#endif /* DETACH */
- X}
- X
- Xvoid set_signals(void)
- X{
- X int dump_status(void);
- X signal(SIGPIPE, SIG_IGN);
- X
- X signal(SIGINT, (void *)sigshutdown);
- X signal(SIGTERM, (void *)sigshutdown);
- X
- X#ifdef DETACH
- X signal(SIGUSR2, (void *)logsynch);
- X#else /* DETACH */
- X signal(SIGUSR2, (void *)bailout);
- X#endif /* DETACH */
- X
- X if (debug)
- X return;
- X
- X# ifdef NOCOREDUMP
- X signal(SIGQUIT, (void *)bailout);
- X signal(SIGILL, (void *)bailout);
- X signal(SIGTRAP, (void *)bailout);
- X signal(SIGIOT, (void *)bailout);
- X signal(SIGEMT, (void *)bailout);
- X signal(SIGFPE, (void *)bailout);
- X signal(SIGBUS, (void *)bailout);
- X signal(SIGSEGV, (void *)bailout);
- X signal(SIGSYS, (void *)bailout);
- X signal(SIGTERM, (void *)bailout);
- X signal(SIGXCPU, (void *)bailout);
- X signal(SIGXFSZ, (void *)bailout);
- X signal(SIGVTALRM, (void *)bailout);
- X# endif
- X}
- X
- Xint
- X msec_diff(struct timeval now, struct timeval then)
- X{
- X return ((now.tv_sec - then.tv_sec) * 1000
- X + (now.tv_usec - then.tv_usec) / 1000);
- X}
- X
- Xvoid
- X clearstrings(struct descriptor_data * d)
- X{
- X if (d->output_prefix)
- X {
- X FREE(d->output_prefix);
- X d->output_prefix = 0;
- X }
- X if (d->output_suffix)
- X {
- X FREE(d->output_suffix);
- X d->output_suffix = 0;
- X }
- X}
- X
- Xvoid
- X shutdownsock(struct descriptor_data * d)
- X{
- X if (d->connected)
- X {
- X writelog("DISCONNECT descriptor %d,%d player %s(%d)\n", d->descriptor, d->num, db[d->player].name, d->player);
- X#ifdef CONNECT_MESSAGES
- X announce_disconnect(d->player);
- X#endif /* CONNECT_MESSAGES */
- X } else
- X {
- X writelog("DISCONNECT descriptor %d,%d never connected\n", d->descriptor, d->num);
- X }
- X clearstrings(d);
- X freeqs(d);
- X}
- X
- Xstruct descriptor_data *
- X initializesock(struct sockaddr_in * a)
- X{
- X struct descriptor_data *d;
- X
- X MALLOC(d, struct descriptor_data, 1);
- X d->connected = 0;
- X d->output_prefix = 0;
- X d->output_suffix = 0;
- X d->output_size = 0;
- X d->output.head = 0;
- X d->output.tail = &d->output.head;
- X d->input.head = 0;
- X d->input.tail = &d->input.head;
- X d->raw_input = 0;
- X d->raw_input_at = 0;
- X d->quota = COMMAND_BURST_SIZE;
- X d->last_time = 0;
- X d->address = *a; /* This will be the address of the
- X * concentrator */
- X d->hostname = ""; /* This will be set during connect */
- X
- X welcome_user(d);
- X return d;
- X}
- X
- Xstruct text_block *
- X make_text_block(const char *s, int n)
- X{
- X struct text_block *p;
- X
- X MALLOC(p, struct text_block, 1);
- X MALLOC(p->buf, char, n);
- X bcopy(s, p->buf, n);
- X p->nchars = n;
- X p->start = p->buf;
- X p->nxt = 0;
- X return p;
- X}
- X
- Xvoid
- X add_to_queue(struct text_queue * q, const char *b, int n)
- X{
- X struct text_block *p;
- X
- X if (n == 0)
- X return;
- X
- X p = make_text_block(b, n);
- X p->nxt = 0;
- X *q->tail = p;
- X q->tail = &p->nxt;
- X}
- X
- Xint
- X flush_queue(struct text_queue * q, int n)
- X{
- X struct text_block *p;
- X int really_flushed = 0;
- X
- X n += strlen(flushed_message);
- X
- X while (n > 0 && (p = q->head))
- X {
- X n -= p->nchars;
- X really_flushed += p->nchars;
- X q->head = p->nxt;
- X free_text_block(p);
- X }
- X p = make_text_block(flushed_message, strlen(flushed_message));
- X p->nxt = q->head;
- X q->head = p;
- X if (!p->nxt)
- X q->tail = &p->nxt;
- X really_flushed -= p->nchars;
- X return really_flushed;
- X}
- X
- Xint
- X queue_write(struct descriptor_data * d, const char *b, int n)
- X{
- X int space;
- X
- X space = MAX_OUTPUT - d->output_size - n;
- X if (space < 0)
- X d->output_size -= flush_queue(&d->output, -space);
- X add_to_queue(&d->output, b, n);
- X d->output_size += n;
- X return n;
- X}
- X
- Xint
- X queue_string(struct descriptor_data * d, const char *s)
- X{
- X return queue_write(d, s, strlen(s));
- X}
- X
- Xvoid
- X freeqs(struct descriptor_data * d)
- X{
- X struct text_block *cur, *next;
- X
- X cur = d->output.head;
- X while (cur)
- X {
- X next = cur->nxt;
- X free_text_block(cur);
- X cur = next;
- X }
- X d->output.head = 0;
- X d->output.tail = &d->output.head;
- X
- X cur = d->input.head;
- X while (cur)
- X {
- X next = cur->nxt;
- X free_text_block(cur);
- X cur = next;
- X }
- X d->input.head = 0;
- X d->input.tail = &d->input.head;
- X
- X if (d->raw_input)
- X FREE(d->raw_input);
- X d->raw_input = 0;
- X d->raw_input_at = 0;
- X}
- X
- Xvoid
- X welcome_user(struct descriptor_data * d)
- X{
- X queue_string(d, WELCOME_MESSAGE);
- X file_date(d, NEWS_FILE);
- X# ifdef CONNECT_FILE
- X do_connect_msg(d, CONNECT_FILE);
- X# endif
- X}
- X
- Xvoid
- X goodbye_user(struct descriptor_data * d)
- X{
- X queue_string(d, LEAVE_MESSAGE);
- X}
- X
- Xchar *
- X strsave(const char *s)
- X{
- X char *p;
- X
- X MALLOC(p, char, strlen(s) + 1);
- X
- X if (p)
- X strcpy(p, s);
- X return p;
- X}
- X
- Xvoid
- X save_command(struct descriptor_data * d, const char *command)
- X{
- X add_to_queue(&d->input, command, strlen(command) + 1);
- X}
- X
- Xvoid
- X set_userstring(char **userstring, const char *command)
- X{
- X if (*userstring)
- X {
- X FREE(*userstring);
- X *userstring = 0;
- X }
- X while (*command && isascii(*command) && isspace(*command))
- X command++;
- X if (*command)
- X *userstring = strsave(command);
- X}
- X
- Xint
- X do_command(struct descriptor_data * d, char *command)
- X{
- X if (!strcmp(command, QUIT_COMMAND))
- X {
- X goodbye_user(d);
- X return 0;
- X } else
- X if (!strncmp(command, WHO_COMMAND, strlen(WHO_COMMAND)))
- X {
- X if (d->output_prefix)
- X {
- X queue_string(d, d->output_prefix);
- X queue_write(d, "\n", 1);
- X }
- X dump_users(d, command + strlen(WHO_COMMAND));
- X if (d->output_suffix)
- X {
- X queue_string(d, d->output_suffix);
- X queue_write(d, "\n", 1);
- X }
- X } else
- X if (d->connected &&
- X !strncmp(command, PREFIX_COMMAND, strlen(PREFIX_COMMAND)))
- X {
- X#ifdef ROBOT_MODE
- X if (!Robot(d->player))
- X {
- X#ifndef TINKER
- X notify(d->player,
- X "Only robots can use OUTPUTPREFIX; contact a Wizard.");
- X#else TINKER
- X notify(d->player,
- X "Only robots can use OUTPUTPREFIX; contact a Tinker.");
- X#endif TINKER
- X return 1;
- X }
- X if (!d->connected)
- X return 1;
- X#endif ROBOT_MODE
- X set_userstring(&d->output_prefix, command + strlen(PREFIX_COMMAND));
- X } else
- X if (d->connected &&
- X !strncmp(command, SUFFIX_COMMAND, strlen(SUFFIX_COMMAND)))
- X {
- X#ifdef ROBOT_MODE
- X if (!Robot(d->player))
- X {
- X#ifndef TINKER
- X notify(d->player,
- X "Only robots can use OUTPUTSUFFIX; contact a Wizard.");
- X#else TINKER
- X notify(d->player,
- X "Only robots can use OUTPUTSUFFIX; contact a Tinker.");
- X#endif TINKER
- X return 1;
- X }
- X#endif ROBOT_MODE
- X set_userstring(&d->output_suffix, command + strlen(SUFFIX_COMMAND));
- X } else
- X {
- X if (d->connected)
- X {
- X if (d->output_prefix)
- X {
- X queue_string(d, d->output_prefix);
- X queue_write(d, "\n", 1);
- X }
- X process_command(d->player, command);
- X if (d->output_suffix)
- X {
- X queue_string(d, d->output_suffix);
- X queue_write(d, "\n", 1);
- X }
- X } else
- X {
- X check_connect(d, command);
- X }
- X }
- X return 1;
- X}
- X
- Xvoid
- X check_connect(struct descriptor_data * d, const char *msg)
- X{
- X char command[MAX_COMMAND_LEN];
- X char user[MAX_COMMAND_LEN];
- X char password[MAX_COMMAND_LEN];
- X dbref player;
- X
- X parse_connect(msg, command, user, password);
- X
- X if (!strncmp(command, "co", 2))
- X {
- X player = connect_player(user, password);
- X if (player == NOTHING)
- X {
- X queue_string(d, connect_fail);
- X writelog("FAILED CONNECT %s on descriptor %d,%d\n", user, d->descriptor, d->num);
- X } else
- X {
- X writelog("CONNECTED %s(%d) on descriptor %d,%d %s\n",
- X db[player].name, player, d->descriptor, d->num, d->hostname);
- X d->connected = 1;
- X d->connected_at = time(NULL);
- X d->player = player;
- X do_motd(player);
- X do_look_around(player);
- X#ifdef CONNECT_MESSAGES
- X announce_connect(player);
- X#endif /* CONNECT_MESSAGES */
- X }
- X } else
- X if (!strncmp(command, "cr", 2))
- X {
- X#ifndef REGISTRATION
- X player = create_player(user, password);
- X if (player == NOTHING)
- X {
- X queue_string(d, create_fail);
- X writelog("FAILED CREATE %s on descriptor %d,%d %s\n",
- X user, d->descriptor, d->num, d->hostname);
- X } else
- X {
- X writelog("CREATED %s(%d) on descriptor %d,%d %s\n",
- X db[player].name, player, d->descriptor, d->num, d->hostname);
- X d->connected = 1;
- X d->connected_at = time(0);
- X d->player = player;
- X do_motd(player);
- X do_look_around(player);
- X#ifdef CONNECT_MESSAGES
- X announce_connect(player);
- X#endif /* CONNECT_MESSAGES */
- X }
- X#else
- X queue_string(d, REGISTER_MESSAGE);
- X#endif /* REGISTRATION */
- X } else
- X {
- X welcome_user(d);
- X }
- X}
- X
- Xvoid
- X parse_connect(const char *msg, char *command, char *user, char *pass)
- X{
- X char *p;
- X
- X while (*msg && isascii(*msg) && isspace(*msg))
- X msg++;
- X p = command;
- X while (*msg && isascii(*msg) && !isspace(*msg))
- X *p++ = *msg++;
- X *p = '\0';
- X while (*msg && isascii(*msg) && isspace(*msg))
- X msg++;
- X p = user;
- X while (*msg && isascii(*msg) && !isspace(*msg))
- X *p++ = *msg++;
- X *p = '\0';
- X while (*msg && isascii(*msg) && isspace(*msg))
- X msg++;
- X p = pass;
- X while (*msg && isascii(*msg) && !isspace(*msg))
- X *p++ = *msg++;
- X *p = '\0';
- X}
- X
- Xvoid
- X close_sockets(void)
- X{
- X struct descriptor_data *d, *dnext;
- X struct conc_list *c;
- X char header[4];
- X
- X for (c = firstc; c; c = c->next)
- X {
- X /* conc.c now handles printing the Going Down - Bye message */
- X shutdown(c->sock, 0);
- X close(c->sock);
- X }
- X close(sock);
- X}
- X
- Xvoid
- X emergency_shutdown(void)
- X{
- X close_sockets();
- X}
- X
- Xint
- X bailout(int sig, int code, struct sigcontext * scp)
- X{
- X long *ptr;
- X int i;
- X
- X writelog("BAILOUT: caught signal %d code %d", sig, code);
- X ptr = (long *)scp;
- X for (i = 0; i < sizeof(struct sigcontext); i++)
- X writelog(" %08lx\n", *ptr);
- X panic("PANIC on spurious signal");
- X _exit(7);
- X return 0;
- X}
- X
- Xchar *
- X time_format_1(long dt)
- X{
- X register struct tm *delta;
- X static char buf[64];
- X
- X delta = gmtime(&dt);
- X if (delta->tm_yday > 0)
- X {
- X sprintf(buf, "%dd %02d:%02d",
- X delta->tm_yday, delta->tm_hour, delta->tm_min);
- X } else
- X {
- X sprintf(buf, "%02d:%02d",
- X delta->tm_hour, delta->tm_min);
- X }
- X return buf;
- X}
- X
- Xchar *
- X time_format_2(long dt)
- X{
- X register struct tm *delta;
- X static char buf[64];
- X
- X delta = gmtime(&dt);
- X if (delta->tm_yday > 0)
- X {
- X sprintf(buf, "%dd", delta->tm_yday);
- X } else
- X if (delta->tm_hour > 0)
- X {
- X sprintf(buf, "%dh", delta->tm_hour);
- X } else
- X if (delta->tm_min > 0)
- X {
- X sprintf(buf, "%dm", delta->tm_min);
- X } else
- X {
- X sprintf(buf, "%ds", delta->tm_sec);
- X }
- X return buf;
- X}
- X
- X#ifdef CONNECT_MESSAGES
- Xvoid
- X announce_connect(dbref player)
- X{
- X dbref loc;
- X char buf[BUFFER_LEN];
- X
- X if ((loc = getloc(player)) == NOTHING)
- X return;
- X if (Dark(player) || Dark(loc))
- X return;
- X
- X sprintf(buf, "%s has connected.", db[player].name);
- X
- X notify_except(db[loc].contents, player, buf);
- X}
- X
- Xvoid
- X announce_disconnect(dbref player)
- X{
- X dbref loc;
- X char buf[BUFFER_LEN];
- X
- X if ((loc = getloc(player)) == NOTHING)
- X return;
- X if (Dark(player) || Dark(loc))
- X return;
- X
- X sprintf(buf, "%s has disconnected.", db[player].name);
- X
- X notify_except(db[loc].contents, player, buf);
- X}
- X
- X#endif /* CONNECT_MESSAGES */
- X
- Xint
- X sigshutdown(int sig, int code, struct sigcontext * scp)
- X{
- X writelog("SHUTDOWN: on signal %d code %d\n", sig, code);
- X shutdown_flag = 1;
- X return 0;
- X}
- X
- X#ifdef DETACH
- Xint
- X logsynch()
- X{
- X freopen(logfile, "a", stderr);
- X setbuf(stderr, NULL);
- X writelog("log file reopened\n");
- X return 0;
- X}
- X
- X#endif /* DETACH */
- X
- X#include <sys/stat.h>
- X
- Xvoid
- X file_date(struct descriptor_data * d, char *file)
- X{
- X static char buf[80];
- X extern char *ctime(long *clock);
- X struct stat statb;
- X char *tstring;
- X char *cp;
- X
- X if (stat(file, &statb) == -1)
- X return;
- X
- X tstring = ctime(&statb.st_mtime);
- X if ((cp = (char *)index(tstring, '\n')) != NULL)
- X *cp = '\0';
- X
- X strcpy(buf, "News last updated ");
- X strcat(buf, tstring);
- X strcat(buf, "\n\n");
- X
- X queue_string(d, (char *)buf);
- X}
- X
- Xvoid main_loop()
- X{
- X struct message *ptr;
- X int found, newsock, lastsock, len, loop;
- X int accepting;
- X struct timeval tv;
- X struct sockaddr_in sin;
- X fd_set in, out;
- X char data[1025], *p1, *p2, buffer[1025], header[4];
- X struct conc_list *c, *tempc, *nextc, *lastc;
- X struct descriptor_data *d, *tempd, *nextd;
- X struct timeval last_slice, current_time;
- X struct timeval next_slice;
- X struct timeval slice_timeout;
- X short templen;
- X
- X accepting = 1;
- X lastsock = sock + 1;
- X while (!shutdown_flag)
- X {
- X gettimeofday(¤t_time, (struct timezone *) 0);
- X last_slice = update_quotas(last_slice, current_time);
- X
- X process_commands();
- X
- X if (shutdown_flag)
- X break;
- X
- X next_slice = msec_add(last_slice, COMMAND_TIME_MSEC);
- X slice_timeout = timeval_sub(next_slice, current_time);
- X
- X FD_ZERO(&in);
- X FD_ZERO(&out);
- X
- X FD_SET(sock, &in);
- X for (c = firstc; c; c = c->next)
- X process_output(c);
- X for (c = firstc; c; c = c->next)
- X if (c->sock)
- X {
- X if (c->ilen < BUFSIZE)
- X FD_SET(c->sock, &in);
- X len = c->first ? c->first->len : 0;
- X while (c->first && ((c->olen + len + 2) < BUFSIZE))
- X {
- X templen = c->first->len;
- X bcopy(&templen, c->outgoing + c->olen, 2);
- X bcopy(c->first->data, c->outgoing + c->olen + 2, len);
- X c->olen += len + 2;
- X ptr = c->first;
- X c->first = ptr->next;
- X FREE(ptr->data);
- X FREE(ptr);
- X if (c->last == ptr)
- X c->last = 0;
- X len = c->first ? c->first->len : 0;
- X }
- X if (c->olen)
- X FD_SET(c->sock, &out);
- X }
- X tv.tv_sec = 1000;
- X tv.tv_usec = 0;
- X
- X found = select(lastsock, &in, &out, (fd_set *) 0, &tv);
- X if (found < 0)
- X continue;
- X if (accepting && FD_ISSET(sock, &in))
- X {
- X len = sizeof(sin);
- X newsock = accept(sock, (struct sockaddr *) & sin, &len);
- X if (newsock >= 0)
- X {
- X if (newsock >= lastsock)
- X lastsock = newsock + 1;
- X if (fcntl(newsock, F_SETFL, FNDELAY) == -1)
- X {
- X perror("make_nonblocking: fcntl");
- X }
- X MALLOC(tempc, struct conc_list, 1);
- X tempc->next = firstc;
- X tempc->firstd = 0;
- X tempc->first = 0;
- X tempc->last = 0;
- X tempc->status = 0;
- X /* Imcomming and outgoing I/O buffers */
- X MALLOC(tempc->incoming, char, BUFSIZE);
- X tempc->ilen = 0;
- X MALLOC(tempc->outgoing, char, BUFSIZE);
- X tempc->olen = 0;
- X firstc = tempc;
- X firstc->sock = newsock;
- X writelog("CONCENTRATOR CONNECT: sock %d, addr %x\n", newsock, sin.sin_addr.s_addr);
- X }
- X }
- X for (c = firstc; c; c = nextc)
- X {
- X nextc = c->next;
- X#ifdef CHECKC
- X if (!(c->sock))
- X writelog("CONSISTENCY CHECK: Concentrator found with null socket #\n");
- X#endif
- X if ((FD_ISSET(c->sock, &in)) && (c->ilen < BUFSIZE))
- X {
- X int i;
- X len = recv(c->sock, c->incoming + c->ilen,
- X BUFSIZE - c->ilen, 0);
- X if (len == 0)
- X {
- X struct message *mptr, *tempm;
- X writelog("CONCENTRATOR DISCONNECT: %d\n", c->sock);
- X close(c->sock);
- X d = c->firstd;
- X while (d)
- X {
- X shutdownsock(d);
- X tempd = d;
- X d = d->next;
- X FREE(tempd);
- X }
- X if (firstc == c)
- X firstc = firstc->next;
- X else
- X lastc->next = c->next;
- X FREE(c->incoming);
- X FREE(c->outgoing);
- X mptr = c->first;
- X while (mptr)
- X {
- X tempm = mptr;
- X mptr = mptr->next;
- X FREE(mptr->data);
- X FREE(mptr);
- X }
- X FREE(c);
- X break;
- X } else
- X if (len < 0)
- X {
- X writelog("recv: %s\n", strerror(errno));
- X } else
- X {
- X int num;
- X
- X c->ilen += len;
- X while (c->ilen > 2)
- X {
- X bcopy(c->incoming, &templen, 2);
- X#ifdef CHECKC
- X if (templen < 1)
- X writelog("CONSISTENCY CHECK: Message recived with lenght < 1\n");
- X#endif
- X if (c->ilen >= (templen + 2))
- X {
- X num = *(c->incoming + 2);
- X /* Is it coming from the command user #? */
- X if (num == 0)
- X {
- X /* Proccess commands */
- X switch (*(c->incoming + 3))
- X {
- X case 1: /* connect */
- X d = initializesock(&sin);
- X d->descriptor = c->sock;
- X d->next = c->firstd;
- X c->firstd = d;
- X d->num = *(c->incoming + 4);
- X MALLOC(d->hostname, char,
- X templen - 5);
- X bcopy(c->incoming + 9, d->hostname,
- X templen - 6);
- X *(d->hostname + templen - 7) = 0;
- X#ifdef DEBUG
- X writelog("USER CONNECT %d,%d from host %s\n", c->sock, d->num, d->hostname);
- X#endif
- X break;
- X case 2: /* disconnect */
- X tempd = 0;
- X d = c->firstd;
- X num = *(c->incoming + 4);
- X while (d)
- X {
- X if (d->num == num)
- X {
- X writelog("USER ABORTED CONNECTION %d,%d\n", c->sock, d->num);
- X shutdownsock(d);
- X if (c->firstd == d)
- X c->firstd = d->next;
- X else
- X tempd->next = d->next;
- X FREE(d);
- X break;
- X }
- X tempd = d;
- X d = d->next;
- X }
- X#ifdef CHECKC
- X if (!d)
- X writelog("CONSISTENCY CHECK: Disconnect Received for unknown user %d,%d\n", c->sock, num);
- X#endif
- X break;
- X
- X /*
- X * This take a message from a concentrator, and logs it in
- X * the log file
- X */
- X case 4:
- X {
- X char buffer[2048];
- X bcopy(c->incoming + 4, buffer,
- X templen - 2);
- X *(buffer + templen - 1) = 0;
- X writelog(buffer);
- X break;
- X }
- X#ifdef CHECKC
- X default:
- X writelog("CONSISTENCY CHECK: Received unknown command from concentrator\n");
- X#endif
- X }
- X } else
- X {
- X d = c->firstd;
- X while (d)
- X {
- X if (d->num == num)
- X {
- X process_input(d, c->incoming + 3,
- X templen - 1);
- X break;
- X }
- X d = d->next;
- X }
- X#ifdef CHECKC
- X if (!d)
- X writelog("CONSISTENCY CHECK: Message received for unknown user %d,%d\n", c->sock, num);
- X#endif
- X }
- X bcopy(c->incoming + templen + 2, c->incoming,
- X (c->ilen - templen - 2));
- X c->ilen = c->ilen - templen - 2;
- X } else
- X break;
- X }
- X }
- X }
- X lastc = c;
- X }
- X /* Send data loop */
- X for (c = firstc; c; c = c->next)
- X {
- X if (FD_ISSET(c->sock, &out))
- X {
- X if (c->olen)
- X {
- X len = send(c->sock, c->outgoing, c->olen, 0);
- X if (len > 0)
- X {
- X c->olen -= len;
- X bcopy(c->outgoing + len, c->outgoing, c->olen);
- X }
- X }
- X }
- X }
- X }
- X}
- X
- Xvoid process_output(struct conc_list * c)
- X{
- X struct descriptor_data *d;
- X struct text_block **qp, *cur;
- X short templen;
- X
- X for (d = c->firstd; d; d = d->next)
- X {
- X qp = &d->output.head;
- X cur = *qp;
- X if (cur)
- X {
- X if (cur->nchars < 512)
- X {
- X if ((c->olen + cur->nchars + 3) < BUFSIZE)
- X {
- X templen = cur->nchars + 1;
- X bcopy(&templen, c->outgoing + c->olen, 2);
- X *(c->outgoing + c->olen + 2) = d->num;
- X strncpy(c->outgoing + c->olen + 3, cur->start, cur->nchars);
- X d->output_size -= cur->nchars;
- X c->olen += cur->nchars + 3;
- X if (!cur->nxt)
- X d->output.tail = qp;
- X *qp = cur->nxt;
- X free_text_block(cur);
- X }
- X } else
- X {
- X if ((c->olen + 512 + 3) < BUFSIZE)
- X {
- X templen = 512 + 1;
- X bcopy(&templen, c->outgoing + c->olen, 2);
- X *(c->outgoing + c->olen + 2) = d->num;
- X strncpy(c->outgoing + c->olen + 3, cur->start, 512);
- X d->output_size -= 512;
- X c->olen += 512 + 3;
- X cur->nchars -= 512;
- X cur->start += 512;
- X }
- X }
- X }
- X }
- X}
- X
- Xvoid boot_off(dbref player)
- X{
- X struct conc_list *c;
- X struct descriptor_data *d, *lastd;
- X char header[4];
- X
- X for (c = firstc; c; c = c->next)
- X {
- X lastd = 0;
- X for (d = c->firstd; d; d = d->next)
- X {
- X if (d->connected && d->player == player)
- X {
- X header[0] = 0;
- X header[1] = 2;
- X header[2] = d->num;
- X queue_message(c, header, 3);
- X process_output(c);
- X if (lastd)
- X lastd->next = d->next;
- X else
- X c->firstd = d->next;
- X shutdownsock(d);
- X FREE(d);
- X return;
- X }
- X lastd = d;
- X }
- X }
- X}
- X
- Xvoid queue_message(struct conc_list * c, char *data, int len)
- X{
- X struct message *ptr;
- X
- X MALLOC(ptr, struct message, 1);
- X MALLOC(ptr->data, char, len);
- X ptr->len = len;
- X bcopy(data, ptr->data, len);
- X ptr->next = 0;
- X if (c->last == 0)
- X c->first = ptr;
- X else
- X c->last->next = ptr;
- X c->last = ptr;
- X}
- X
- Xint do_connect_msg(struct descriptor_data * d, const char *filename)
- X{
- X FILE *f;
- X char buf[BUFFER_LEN];
- X char *p;
- X
- X if ((f = fopen(filename, "r")) == NULL)
- X {
- X return (0);
- X } else
- X {
- X while (fgets(buf, sizeof buf, f))
- X {
- X queue_string(d, (char *)buf);
- X
- X }
- X fclose(f);
- X return (1);
- X }
- X}
- END_OF_FILE
- if test 33958 -ne `wc -c <'interface.c'`; then
- echo shar: \"'interface.c'\" unpacked with wrong size!
- fi
- # end of 'interface.c'
- fi
- if test -f 'joinspl.sh' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'joinspl.sh'\"
- else
- echo shar: Extracting \"'joinspl.sh'\" \(333 characters\)
- sed "s/^X//" >'joinspl.sh' <<'END_OF_FILE'
- X#! /bin/sh
- X#
- X# join split lines in the config.h and small.db files
- X#
- Xecho creating config.h
- Xsed -f comb.sed config_h.spl >config.h
- Xecho creating small.db
- Xsed -f comb.sed smalldb.spl >small.db
- Xrm config_h.spl smalldb.spl
- X#
- X# build tinymud.ps from its three parts
- X#
- Xcreating tinymud.ps
- Xcat tinymud.ps.xa? >tinymud.ps
- Xrm tinymud.ps.xa?
- END_OF_FILE
- if test 333 -ne `wc -c <'joinspl.sh'`; then
- echo shar: \"'joinspl.sh'\" unpacked with wrong size!
- fi
- chmod +x 'joinspl.sh'
- # end of 'joinspl.sh'
- fi
- if test -f 'wiz.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'wiz.c'\"
- else
- echo shar: Extracting \"'wiz.c'\" \(16849 characters\)
- sed "s/^X//" >'wiz.c' <<'END_OF_FILE'
- X#include "copyright.h"
- X
- X/* Wizard-only commands */
- X
- X
- X#include "db.h"
- X#include "config.h"
- X#include "interface.h"
- X#include "match.h"
- X#include "externs.h"
- X
- Xvoid do_teleport(dbref player, const char *arg1, const char *arg2)
- X{
- X dbref victim;
- X dbref destination;
- X const char *to;
- X
- X#ifdef RESTRICTED_TELEPORT
- X if(!Wizard(player)) {
- X#ifndef TINKER
- X notify(player, "Only a Wizard may teleport at will.");
- X#else TINKER
- X notify(player, "Only a Tinker may teleport at will.");
- X#endif TINKER
- X return;
- X }
- X#endif /* RESTRICTED_TELEPORT */
- X
- X /* get victim, destination */
- X if(*arg2 == '\0') {
- X victim = player;
- X to = arg1;
- X } else {
- X init_match(player, arg1, NOTYPE);
- X match_neighbor();
- X match_possession();
- X match_me();
- X match_absolute();
- X match_player();
- X
- X if((victim = noisy_match_result()) == NOTHING) {
- X return;
- X }
- X to = arg2;
- X }
- X
- X /* get destination */
- X init_match(player, to, TYPE_PLAYER);
- X match_here();
- X match_absolute();
- X if(Wizard(player)) {
- X match_neighbor();
- X match_me();
- X match_player();
- X }
- X
- X switch(destination = match_result()) {
- X case NOTHING:
- X notify(player, "Send it where?");
- X break;
- X case AMBIGUOUS:
- X notify(player, "I don't know which destination you mean!");
- X break;
- X default:
- X /* check victim, destination types, teleport if ok */
- X if(Typeof(destination) == TYPE_EXIT
- X || Typeof(destination) == TYPE_THING
- X || Typeof(victim) == TYPE_EXIT
- X || Typeof(victim) == TYPE_ROOM
- X || (Typeof(victim) == TYPE_PLAYER
- X && Typeof(destination) != TYPE_ROOM)) {
- X notify(player, "Bad destination.");
- X#ifndef RESTRICTED_TELEPORT
- X } else if(!Wizard(player)
- X && !(Typeof(victim) == TYPE_THING
- X && Typeof(destination) == TYPE_ROOM
- X && (controls(player, victim)
- X || (Typeof(db[victim].location) == TYPE_ROOM
- X && controls(player, db[victim].location)))
- X && (can_link_to(player, TYPE_PLAYER, destination)))) {
- X notify(player, "Permission denied.");
- X#endif /* RESTRICTED_TELEPORT */
- X } else if(Typeof(victim) == TYPE_PLAYER) {
- X notify(victim, "You feel a wrenching sensation...");
- X enter_room(victim, destination);
- X notify(player, "Teleported.");
- X } else {
- X /* check for non-sticky dropto */
- X if(Typeof(destination) == TYPE_ROOM
- X && db[destination].location != NOTHING
- X && !(db[destination].flags & STICKY)) {
- X /* destination has immediate dropto */
- X destination = db[destination].location;
- X }
- X
- X /* do the move */
- X moveto(victim, destination);
- X notify(player, "Teleported.");
- X }
- X }
- X}
- X
- Xvoid do_mass_teleport(dbref player, const char *arg1)
- X{
- X dbref victim;
- X dbref destination;
- X char buf[BUFFER_LEN];
- X int moved = 0;
- X
- X if(!God(player)) {
- X#ifndef TINKER
- X notify(player, "Only God can do a mass teleport.");
- X#else TINKER
- X notify(player, "Only the Master Tinker can do a mass teleport.");
- X#endif TINKER
- X return;
- X }
- X
- X /* get destination */
- X init_match(player, arg1, TYPE_ROOM);
- X match_here();
- X match_absolute();
- X
- X if ((destination = match_result()) == NOTHING) {
- X notify(player, "Please specify a destination to send everyone to.");
- X return;
- X }
- X
- X switch (Typeof(destination)) {
- X case NOTHING:
- X notify(player, "Send them where?");
- X break;
- X
- X case TYPE_ROOM:
- X for (victim = 0; victim < db_top; victim++) {
- X if (victim != player && Typeof(victim) == TYPE_PLAYER) {
- X notify(victim,
- X "You and everyone around you feels a wrenching sensation...");
- X moveto(victim, destination);
- X look_room(victim, destination);
- X moved++;
- X }
- X }
- X sprintf (buf, "Teleported %d players to %s.",
- X moved, unparse_object (player, destination));
- X notify(player, "Teleported.");
- X break;
- X
- X default:
- X notify(player, "Mass teleports are legal to rooms only.");
- X }
- X}
- X
- Xvoid do_force(dbref player, const char *what, char *command)
- X{
- X dbref victim;
- X
- X if(!Wizard(player)) {
- X writelog ("FORCE: failed, priv, player %s(%d), who '%s', what '%s'\n",
- X db[player].name, player, what, command);
- X#ifndef TINKER
- X notify(player, "Only Wizards may use this command.");
- X#else TINKER
- X notify(player, "Only Tinkers may use this command.");
- X#endif TINKER
- X return;
- X }
- X
- X /* get victim */
- X if((victim = lookup_player(what)) == NOTHING) {
- X writelog ("FORCE: failed, victim, player %s(%d), who '%s', what '%s'\n",
- X db[player].name, player, what, command);
- X notify(player, "That player does not exist.");
- X return;
- X }
- X
- X#ifdef GOD_PRIV
- X if(God(victim)) {
- X#ifndef TINKER
- X writelog ("FORCE: failed, wizard, player %s(%d), who '%s', what '%s'\n",
- X#else TINKER
- X writelog ("FORCE: failed, tinker, player %s(%d), who '%s', what '%s'\n",
- X#endif TINKER
- X db[player].name, player, what, command);
- X#ifndef TINKER
- X notify(player, "You can't force God.");
- X#else TINKER
- X notify(player, "You can't force the Master Tinker.");
- X#endif TINKER
- X return;
- X }
- X#endif GOD_PRIV
- X
- X /* force victim to do command */
- X writelog ("FORCE: success, player %s(%d), who '%s', what '%s'\n",
- X db[player].name, player, what, command);
- X
- X process_command(victim, command);
- X}
- X
- Xvoid do_stats(dbref player, const char *name)
- X{
- X dbref rooms;
- X dbref exits;
- X dbref things;
- X dbref players;
- X dbref total;
- X dbref i;
- X dbref owner;
- X char buf[BUFFER_LEN];
- X
- X if(!Wizard(player)) {
- X sprintf(buf, "The universe contains %d objects.", db_top);
- X notify(player, buf);
- X } else {
- X owner = lookup_player(name);
- X total = rooms = exits = things = players = 0;
- X for(i = 0; i < db_top; i++) {
- X if(owner == NOTHING || owner == db[i].owner) {
- X total++;
- X switch(Typeof(i)) {
- X case TYPE_ROOM:
- X rooms++;
- X break;
- X case TYPE_EXIT:
- X exits++;
- X break;
- X case TYPE_THING:
- X things++;
- X break;
- X case TYPE_PLAYER:
- X players++;
- X break;
- X default:
- X abort();
- X break;
- X }
- X }
- X }
- X sprintf(buf,
- X "%d objects = %d rooms, %d exits, %d things, %d players.",
- X total, rooms, exits, things, players);
- X notify(player, buf);
- X#ifdef TEST_MALLOC
- X sprintf(buf, "Malloc count = %d.", malloc_count);
- X notify(player, buf);
- X#endif /* TEST_MALLOC */
- X }
- X}
- X
- Xvoid do_bobble(dbref player, const char *name, const char *rname)
- X{
- X dbref victim, recip, i;
- X char buf[BUFFER_LEN];
- X int newflags = 0;
- X
- X if(!Wizard(player)) {
- X#ifndef TINKER
- X writelog("TOAD: failed, priv %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X notify(player, "Only a Wizard can turn a person into a toad.");
- X#else TINKER
- X writelog("BOBBLE: failed, priv %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X notify(player, "Only a Tinker can bobble a person.");
- X#endif TINKER
- X return;
- X }
- X
- X if (!name || !*name) {
- X#ifndef TINKER
- X writelog("TOAD: failed, syntax %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#else TINKER
- X writelog("BOBBLE: failed, syntax %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#endif TINKER
- X notify(player, "You must specify a victim.");
- X return;
- X }
- X
- X init_match(player, name, TYPE_PLAYER);
- X match_neighbor();
- X match_absolute();
- X match_player();
- X if((victim = noisy_match_result()) == NOTHING) {
- X#ifndef TINKER
- X writelog("TOAD: failed, victim %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#else TINKER
- X writelog("BOBBLE: failed, victim %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#endif TINKER
- X notify(player, "Please specify another victim.");
- X return;
- X }
- X
- X#ifdef RECYCLE
- X /* Default the recipient to RECYCLER */
- X if (!rname || !*rname || string_compare (rname, RECYCLER) == 0) {
- X recip = lookup_player(RECYCLER);
- X newflags = UNWANTED; /* Can be gotten by other players */
- X } else {
- X recip = lookup_player(rname);
- X }
- X#else
- X recip = lookup_player(rname);
- X#endif
- X
- X if(recip == NOTHING || recip == victim) {
- X#ifndef TINKER
- X writelog("TOAD: failed, recip %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#else TINKER
- X writelog("BOBBLE: failed, recip %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#endif TINKER
- X notify(player, "Please specify another player to own the victim's effects.");
- X return;
- X }
- X
- X if(Typeof(victim) != TYPE_PLAYER) {
- X#ifndef TINKER
- X writelog("TOAD: failed, type %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X notify(player, "You can only turn players into toads!");
- X#else TINKER
- X writelog("BOBBLE: failed, type %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X notify(player, "You can only bobble players!");
- X#endif TINKER
- X } else if(Wizard(victim)) {
- X#ifndef TINKER
- X writelog("TOAD: failed, wizard %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X notify(player, "You can't turn a Wizard into a toad.");
- X#else TINKER
- X writelog("BOBBLE: failed, tinker %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X notify(player, "You can't bobble a Tinker.");
- X#endif TINKER
- X } else if(db[victim].contents != NOTHING) {
- X#ifndef TINKER
- X writelog("TOAD: failed, contents %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#else TINKER
- X writelog("BOBBLE: failed, contents %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#endif TINKER
- X
- X notify(player, "What about what they are carrying?");
- X } else {
- X#ifndef TINKER
- X writelog("TOAD: success %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#else TINKER
- X writelog("BOBBLE: success %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#endif TINKER
- X
- X /* we are ok */
- X /* do it */
- X if(db[victim].password) {
- X free((void *) db[victim].password);
- X db[victim].password = 0;
- X }
- X db[victim].flags = TYPE_THING;
- X
- X /* Give the sphere and all old belongings to recipient */
- X db[victim].owner = recip;
- X for (i=0; i<db_top; i++) {
- X if (db[i].owner == victim) {
- X db[i].owner = recip;
- X db[i].flags |= newflags;
- X }
- X }
- X
- X db[victim].pennies = 1; /* dont let him keep his immense wealth */
- X
- X /* notify people */
- X#ifndef TINKER
- X sprintf(buf, "You have been turned into a toad by %s.",
- X db[player].name);
- X#else TINKER
- X sprintf(buf, "You have been encased in a stasis sphere by %s.",
- X db[player].name);
- X#endif TINKER
- X notify(victim, buf);
- X#ifndef TINKER
- X sprintf(buf, "You turned %s into a toad!", db[victim].name);
- X#else TINKER
- X sprintf(buf, "You bobbled %s!", db[victim].name);
- X#endif TINKER
- X notify(player, buf);
- X
- X /* reset name */
- X#ifdef PLAYER_LIST
- X delete_player(victim);
- X#endif PLAYER_LIST
- X#ifndef TINKER
- X sprintf(buf, "a slimy toad named %s", db[victim].name);
- X#else TINKER
- X sprintf(buf, "a silvery sphere containing %s", db[victim].name);
- X#endif TINKER
- X free((void *) db[victim].name);
- X db[victim].name = alloc_string(buf);
- X }
- X}
- X
- Xvoid do_unbobble(dbref player, const char *name, const char *newname)
- X{
- X dbref victim;
- X char buf[BUFFER_LEN];
- X
- X if(!Wizard(player)) {
- X#ifndef TINKER
- X writelog("UNTOAD: failed, priv %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X notify(player, "Only a Wizard can turn a toad into a person.");
- X#else TINKER
- X writelog("UNBOBBLE: failed, priv %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X notify(player, "Only a Tinker can unbobble a person.");
- X#endif TINKER
- X return;
- X }
- X
- X if (!name || !*name) {
- X#ifndef TINKER
- X writelog("UNTOAD: failed, syntax %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#else TINKER
- X writelog("UNBOBBLE: failed, syntax %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#endif TINKER
- X notify(player, "You must specify a thing.");
- X return;
- X }
- X
- X if (!newname || !*newname) {
- X#ifndef TINKER
- X writelog("UNTOAD: failed, syntax %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X notify(player,"You must specify a new name: @untoad <thing> = <name>");
- X#else TINKER
- X writelog("UNBOBBLE: failed, syntax %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X notify(player,
- X "You must specify a new name: @unbobble <thing> = <name>");
- X#endif TINKER
- X return;
- X }
- X
- X init_match(player, name, TYPE_THING);
- X match_neighbor();
- X match_absolute();
- X match_player();
- X if((victim = noisy_match_result()) == NOTHING) {
- X#ifndef TINKER
- X writelog("UNTOAD: failed, victim %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#else TINKER
- X writelog("UNBOBBLE: failed, victim %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#endif TINKER
- X notify(player, "Please specify another thing.");
- X return;
- X }
- X
- X if(Typeof(victim) != TYPE_THING) {
- X#ifndef TINKER
- X writelog("UNTOAD: failed, type %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X notify(player, "You can only turn players into toads!");
- X#else TINKER
- X writelog("UNBOBBLE: failed, type %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X notify(player, "You can only bobble players!");
- X#endif TINKER
- X } else if (!ok_player_name(newname)) {
- X#ifndef TINKER
- X writelog("UNTOAD: failed, name %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#else TINKER
- X writelog("UNBOBBLE: failed, name %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#endif TINKER
- X notify(player, "You can't give a player that name!");
- X } else {
- X#ifndef TINKER
- X writelog("UNTOAD: success %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#else TINKER
- X writelog("UNBOBBLE: success %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X#endif TINKER
- X
- X /* we are ok */
- X /* do it */
- X db[victim].flags = TYPE_PLAYER;
- X db[victim].owner = victim;
- X db[victim].pennies = KILL_BONUS;
- X
- X /* reset name */
- X free((void *) db[victim].name);
- X db[victim].name = alloc_string(newname);
- X
- X#ifndef TINKER
- X sprintf(buf, "You turned the toad back into %s!", db[victim].name);
- X#else TINKER
- X sprintf(buf, "You unbobbled %s!", db[victim].name);
- X#endif TINKER
- X notify(player, buf);
- X
- X sprintf(buf, "Use @newpassword to give %s a password",
- X db[victim].name);
- X notify(player, buf);
- X
- X#ifdef PLAYER_LIST
- X add_player(victim);
- X#endif PLAYER_LIST
- X }
- X}
- X
- Xvoid do_newpassword(dbref player, const char *name, const char *password)
- X{
- X dbref victim;
- X char buf[BUFFER_LEN];
- X
- X if(!Wizard(player)) {
- X writelog("PASSWORD: failed, priv %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X notify(player, "Your delusions of grandeur have been duly noted.");
- X return;
- X } else if((victim = lookup_player(name)) == NOTHING) {
- X writelog("PASSWORD: failed, victim %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X notify(player, "No such player.");
- X } else if(*password != '\0' && !ok_password(password)) {
- X /* Wiz can set null passwords, but not bad passwords */
- X writelog("PASSWORD: failed, password %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X notify(player, "Bad password");
- X#ifdef GOD_PRIV
- X } else if (God(victim) && !God(player)) {
- X#ifndef TINKER
- X writelog("PASSWORD: failed, wizard %s(%d) who '%s'\n",
- X#else TINKER
- X writelog("PASSWORD: failed, tinker %s(%d) who '%s'\n",
- X#endif TINKER
- X db[player].name, player, name);
- X notify(player, "You cannot change that player's password.");
- X#endif GOD_PRIV
- X } else {
- X writelog("PASSWORD: success %s(%d) who '%s'\n",
- X db[player].name, player, name);
- X /* it's ok, do it */
- X if(db[victim].password) free((void *) db[victim].password);
- X db[victim].password = alloc_string(password);
- X notify(player, "Password changed.");
- X sprintf(buf, "Your password has been changed by %s.", db[player].name);
- X notify(victim, buf);
- X }
- X}
- X
- Xvoid do_boot(dbref player, const char *name)
- X{
- X dbref victim;
- X char buf[BUFFER_LEN];
- X
- X if(!Wizard(player)) {
- X writelog ("BOOT: failed, priv player %s(%d), who '%s'\n",
- X db[player].name, player, name);
- X
- X#ifndef TINKER
- X notify(player, "Only a Wizard can boot another player off!");
- X#else TINKER
- X notify(player, "Only a Tinker can boot another player off!");
- X#endif TINKER
- X return;
- X }
- X
- X init_match(player, name, TYPE_PLAYER);
- X match_neighbor();
- X match_absolute();
- X match_player();
- X if((victim = noisy_match_result()) == NOTHING) return;
- X
- X#ifdef GOD_PRIV
- X if(God(victim)) {
- X#ifndef TINKER
- X writelog ("BOOT: failed, wizard, player %s(%d), who '%s'\n",
- X#else TINKER
- X writelog ("BOOT: failed, tinker, player %s(%d), who '%s'\n",
- X#endif TINKER
- X db[player].name, player, name);
- X
- X notify(player, "You can't boot that player!");
- X return;
- X }
- X#endif GOD_PRIV
- X
- X if(Typeof(victim) != TYPE_PLAYER) {
- X writelog ("BOOT: failed, victim, player %s(%d), who '%s'\n",
- X db[player].name, player, name);
- X
- X notify(player, "You can only boot off other players!");
- X } else {
- X writelog ("BOOT: success, player %s(%d), who '%s'\n",
- X db[player].name, player, name);
- X
- X /* we are ok */
- X /* do it */
- X /* notify people */
- X sprintf(buf, "You have been booted off the game by %s.",
- X db[player].name);
- X notify(victim, buf);
- X sprintf(buf, "You booted %s off!", db[victim].name);
- X notify(player, buf);
- X boot_off(victim);
- X /* reset name */
- X }
- X}
- END_OF_FILE
- if test 16849 -ne `wc -c <'wiz.c'`; then
- echo shar: \"'wiz.c'\" unpacked with wrong size!
- fi
- # end of 'wiz.c'
- fi
- echo shar: End of archive 5 \(of 10\).
- cp /dev/null ark5isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 10 archives.
- echo ">>> now type 'sh joinspl.sh'"
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-